package org.phalanx.server.game;

import java.sql.SQLException;
import java.util.ArrayList;

import org.phalanx.game.units.PhalanxMapUnitSet;
import org.phalanx.map.PhalanxMap;
import org.phalanx.map.PhalanxMapWriter;
import org.phalanx.server.PhalanxServer;
import org.phalanx.server.ServerCache.AbstractCacheHandler;
import org.phalanx.server.ServerCache.Cache;
import org.phalanx.server.ServerCache.CacheManager;
import org.phalanx.server.ServerCache.Cacheable;
import org.phalanx.server.ServerCache.QueryObject;
import org.phalanx.server.sql.SQLAction;
import org.phalanx.server.sql.SQLManager;

public class GameListCacheHandler implements AbstractCacheHandler {
	public static final String tableName = "game";

	public static final String GAMEID = "gameid";
	public static final String NUMBER_OF_PLAYERS = "numplayers";
	public static final String MAP_ID = "mapid";
	public static final String TURN_MODE = "turnmode";
	public static final String TURN_TIME = "turntime";
	public static final String GAME_NAME = "gamename";
	public static final String CURRENT_TURN = "currentturn";
	public static final String GAME_CREATOR = "gamecreator";

	private PhalanxMapUnitSet uSet;

	public GameListCacheHandler(PhalanxMapUnitSet uSet){
		this.uSet = uSet;
	}

	@Override
	public boolean addElementToDB(Cache c, Object newKey, Cacheable newElement) {
		boolean isSuccess = false;
		SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();

		try {
			if (newElement != null && newKey != null){
				PhalanxGameSettings settings = (PhalanxGameSettings)newElement;
				Integer gameId = (Integer)newKey;
				
				CacheManager cacheMgr = PhalanxServer.getServerInstance().getCacheManager();
				
				SQLAction addingGameList = new SQLAction(SQLAction.INSERT, tableName);

				addingGameList.addField(GAMEID);
				addingGameList.addField(NUMBER_OF_PLAYERS);
				addingGameList.addField(MAP_ID);
				addingGameList.addField(TURN_MODE);
				addingGameList.addField(TURN_TIME);
				addingGameList.addField(GAME_NAME);
				addingGameList.addField(CURRENT_TURN);
				addingGameList.addField(GAME_CREATOR);

				addingGameList.addValues(settings.getId().toString());
				addingGameList.addValues(settings.getNumberOfPlayers().toString());
				addingGameList.addValues(settings.getMapName().toString());
				addingGameList.addValues(settings.getTurnMode().toString());
				addingGameList.addValues(settings.getTurnTime() == null ? null : settings.getTurnTime().toString());
				addingGameList.addValues(settings.getGameName());
				addingGameList.addValues(settings.getCurrentTurn().toString());
				addingGameList.addValues(settings.getGameCreatorId().toString());

				sqlMan.insertQuery(addingGameList.getActionString());
				
				/*PhalanxMapCacheWrapper gameMapWrap = (PhalanxMapCacheWrapper)cacheMgr.getElement("PhalanxMapCache", settings.getMapName());
				PhalanxBattleRPGEngine rpgEngine = new PhalanxBattleRPGEngine(gameId, gameMapWrap.getMap());
				cacheMgr.setElement("GameEngineCache", gameId, rpgEngine);

				PhalanxGameTurnTimer pTimer = new PhalanxGameTurnTimer(gameId);
				pTimer.setPaused(false);
				cacheMgr.setElement("PlayerTurnTimer", gameId, new TimerCacheWrapper(pTimer));*/

				isSuccess = true;
			}
		} catch (SQLException se){
			se.printStackTrace();
		}

		return isSuccess;
	}

	@Override
	public boolean deleteObjectFromDB(Cache c, Object newKey,
			Cacheable newElement) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public ArrayList<Cacheable> getMultipleObjectsFromDB(Cache c,
			Object newKey, boolean cacheUpdate) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Cacheable getObjectFromDB(Cache c, Object newKey, boolean cacheUpdate) {
		PhalanxGameSettings newSettings = null;

		if (newKey != null){
			try {
				SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();
				ArrayList<QueryObject> results = new ArrayList<QueryObject>();

				QueryObject gameListQuery = new QueryObject();
				gameListQuery.setInteger(GAMEID, 0);
				gameListQuery.setInteger(NUMBER_OF_PLAYERS, 0);
				gameListQuery.setString(MAP_ID, new String());
				gameListQuery.setInteger(TURN_MODE, 0);
				gameListQuery.setInteger(TURN_TIME, 0);
				gameListQuery.setString(GAME_NAME, new String());
				gameListQuery.setInteger(CURRENT_TURN, 0);
				gameListQuery.setInteger(GAME_CREATOR, 0);

				SQLAction getGame = new SQLAction(SQLAction.SELECT, tableName);
				getGame.addField("*");
				getGame.addSearchCriteriaAND(GAMEID, SQLAction.EQUALS, newKey.toString());

				results = sqlMan.getQuery(getGame.getActionString(), gameListQuery);
				
				if (!results.isEmpty()){
					QueryObject importantQuery = results.get(0); // Only care about the first one just incase of duplicates
					
					newSettings = new PhalanxGameSettings();
					
					newSettings.setId(importantQuery.getInteger(GAMEID));
					newSettings.setNumberOfPlayers(importantQuery.getInteger(NUMBER_OF_PLAYERS));
					newSettings.setMapName(importantQuery.getString(MAP_ID));
					newSettings.setTurnMode(importantQuery.getInteger(TURN_MODE));
					newSettings.setTurnTime(importantQuery.getInteger(TURN_TIME));
					newSettings.setGameName(importantQuery.getString(GAME_NAME));
					newSettings.setCurrentTurn(importantQuery.getInteger(CURRENT_TURN));
					newSettings.setGameCreatorId(importantQuery.getInteger(GAME_CREATOR));
					
					if (cacheUpdate){
						c.put(newSettings.getId(), newSettings);
					}
				}
				
			} catch (SQLException se){
				se.printStackTrace();
			}

		}
		return newSettings;
	}

	@Override
	public boolean populateCache(Cache c) {
		boolean isSuccess = false;

		SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();
		ArrayList<QueryObject> results = new ArrayList<QueryObject>();

		CacheManager cacheMgr = PhalanxServer.getServerInstance().getCacheManager();

		QueryObject gameListQuery = new QueryObject();
		gameListQuery.setInteger(GAMEID, 0);
		gameListQuery.setInteger(NUMBER_OF_PLAYERS, 0);
		gameListQuery.setString(MAP_ID, new String());
		gameListQuery.setInteger(TURN_MODE, 0);
		gameListQuery.setInteger(TURN_TIME, 0);
		gameListQuery.setString(GAME_NAME, new String());
		gameListQuery.setInteger(CURRENT_TURN, 0);
		gameListQuery.setInteger(GAME_CREATOR, 0);

		SQLAction getAllUsers = new SQLAction(SQLAction.SELECT, tableName);
		getAllUsers.addField("*");

		try {
			results = sqlMan.getQuery(getAllUsers.getActionString(), gameListQuery);


			for (int i = 0; i < results.size(); i++){
				QueryObject temp = results.get(i);
				Integer gameId = temp.getInteger(GAMEID);

				PhalanxGameSettings gameListItem = new PhalanxGameSettings();
				gameListItem.setId(gameId);
				gameListItem.setNumberOfPlayers(temp.getInteger(NUMBER_OF_PLAYERS));
				gameListItem.setMapName(temp.getString(MAP_ID));
				gameListItem.setTurnMode(temp.getInteger(TURN_MODE));
				gameListItem.setTurnTime(temp.getInteger(TURN_TIME));
				gameListItem.setGameName(temp.getString(GAME_NAME));
				gameListItem.setCurrentTurn(temp.getInteger(CURRENT_TURN));
				gameListItem.setGameCreatorId(temp.getInteger(GAME_CREATOR));
				gameListItem.setUnitSet(uSet);

				c.put(gameListItem.getId(),gameListItem);

				PhalanxMapCacheWrapper gameMapWrap = (PhalanxMapCacheWrapper)cacheMgr.getElement("PhalanxMapCache", temp.getString(MAP_ID));
				PhalanxBattleRPGEngine rpgEngine = new PhalanxBattleRPGEngine(gameId, gameMapWrap.getMap());
				cacheMgr.setElement("GameEngineCache", gameId, rpgEngine);

				PhalanxGameTurnTimer pTimer = new PhalanxGameTurnTimer(gameId);
				pTimer.setPaused(true);
				cacheMgr.setElement("PlayerTurnTimer", gameId, new TimerCacheWrapper(pTimer));

			}
			isSuccess = true;
		} catch (SQLException se){
			se.printStackTrace();
		}

		return isSuccess;
	}

	@Override
	public boolean updateElementToDB(Cache c, Object newKey,
			Cacheable newElement) {
		boolean isSuccess = false;

		try {
		SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();
		PhalanxGameSettings updatedSettings = (PhalanxGameSettings)newElement;
		
		SQLAction updatingGameList = new SQLAction(SQLAction.UPDATE, tableName);
		updatingGameList.addSearchCriteriaAND(GAMEID, SQLAction.EQUALS, updatedSettings.getId().toString());

		updatingGameList.addField(GAMEID);
		updatingGameList.addField(NUMBER_OF_PLAYERS);
		updatingGameList.addField(MAP_ID);
		updatingGameList.addField(TURN_MODE);
		updatingGameList.addField(TURN_TIME);
		updatingGameList.addField(GAME_NAME);
		updatingGameList.addField(CURRENT_TURN);
		updatingGameList.addField(GAME_CREATOR);

		updatingGameList.addValues(updatedSettings.getId().toString());
		updatingGameList.addValues(updatedSettings.getNumberOfPlayers().toString());
		updatingGameList.addValues(updatedSettings.getMapName().toString());
		updatingGameList.addValues(updatedSettings.getTurnMode().toString());
		updatingGameList.addValues(updatedSettings.getTurnTime() == null ? null : updatedSettings.getTurnTime().toString());
		updatingGameList.addValues(updatedSettings.getGameName());
		updatingGameList.addValues(updatedSettings.getCurrentTurn().toString());
		updatingGameList.addValues(updatedSettings.getGameCreatorId().toString());

		sqlMan.insertQuery(updatingGameList.getActionString());
		
		isSuccess = true;
		
		} catch (SQLException se){
			se.printStackTrace();
		}
		
		
		return isSuccess;
	}

}
